﻿using Dpy.Math.Geometry.Geometry2D;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace MathWpfClient.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        public ObservableCollection<ViewModelBase> DrawableObjects { get; set; }

        public MainViewModel()
        {
            this.DrawableObjects = this.GetViewModelsFromGeometries(this.YieldShitsHere());
        }

        public ObservableCollection<ViewModelBase> GetViewModelsFromGeometries(IEnumerable<object> geometries)
        {
            var result = new ObservableCollection<ViewModelBase>();

            foreach (var geometry in geometries)
            {
                result.Add(this.GetViewModelFromGeometry(geometry));
            }

            return result;
        }

        public ViewModelBase GetViewModelFromGeometry(object geometry)
        {
            if (geometry is Vector2D)
            {
                return new PointViewModel(geometry as Vector2D);
            }
            else if (geometry is LineSegment2D)
            {
                return new LineSegmentViewModel(geometry as LineSegment2D);
            }
            else if (geometry is Circle)
            {
                return new CircleViewModel(geometry as Circle);
            }

            throw new ArgumentException("Not supported geometry object!");
        }

        public IEnumerable<object> YieldShitsHere()
        {
            IEnumerable<LineSegment2D> segments = this.YieldLineSegments();
            foreach (var laino in segments)
            {
                yield return laino;
            }

            IEnumerable<Vector2D> segmentsIntersections = this.IntersectLineSegments(segments);
            foreach (var laino in segmentsIntersections)
            {
                yield return laino;
            }

            IEnumerable<Circle> circles = this.YieldCircles();
            foreach (var laino in circles)
            {
                yield return laino;
            }

            IEnumerable<Vector2D> segmentsCirclesIntersections = this.IntersectLineSegmentsWithCircles(segments, circles);
            foreach (var laino in segmentsCirclesIntersections)
            {
                yield return laino;
            }
        }

        public IEnumerable<Circle> YieldCircles()
        {
            yield return new Circle(new Vector2D(50, 50), 50);
            yield return new Circle(new Vector2D(50, 50), 100);
            yield return new Circle(new Vector2D(250, 150), 100);
        }

        public IEnumerable<Vector2D> IntersectLineSegmentsWithCircles(IEnumerable<LineSegment2D> segments, IEnumerable<Circle> circles)
        {
            foreach (var segment in segments.ToArray())
            {
                foreach (var circle in circles.ToArray())
                {
                    Vector2D[] points = segment.IntersectWith(circle);
                    foreach (var p in points)
                    {
                        yield return p;
                    }
                }
            }
        }

        public IEnumerable<LineSegment2D> YieldLineSegments()
        {
            yield return new LineSegment2D(new Vector2D(5, 5), new Vector2D(500, 500));
            yield return new LineSegment2D(new Vector2D(50, 5), new Vector2D(5, 50));
            yield return new LineSegment2D(new Vector2D(50, 5), new Vector2D(5, 500));
            yield return new LineSegment2D(new Vector2D(60, 15), new Vector2D(15, 510));
        }

        public IEnumerable<Vector2D> IntersectLineSegments(IEnumerable<LineSegment2D> segments)
        {
            foreach (var a in segments.ToArray())
            {
                foreach (var b in segments.ToArray())
                {
                    Vector2D p = a.IntersectWith(b);
                    if (p != null)
                    {
                        yield return p;
                    }
                }
            }
        }

    }
}
